---
title: 多阶段构建镜像
sidebar_position: 3
---

在镜像构建中有一种叫做"多阶段构建"的方式, 就是会将镜像的构建过程分为多个阶段, 每个阶段可以使用不同的基础镜像, 也可以使用之前构建阶段中生成的内容, 好处是可以使构建的粒度更细, 生成更多可以不断复用的层镜像, 这些镜像可以在后续的构建阶段中作为缓存被引用, 从而加快镜像的构建速度, 同时这种分层的方式也可以降低最终生成的镜像大小

下面列一下本站点所使用的 [`Dockerfile` 文件](https://github.com/CollapseNav/CollapseNav.Net.Tool-Doc/blob/main/dockerfile)

```yml
# 使用node镜像通过 package.json 安装依赖, 由于 package.json 一般不会频繁变更, 所以此处可作为缓存层
FROM node:lts-alpine as initnode
WORKDIR /src
COPY ./package.json ./package.json
RUN yarn config set registry https://registry.npmmirror.com/ && yarn install

# 使用已经包含依赖的镜像进行构建, 但是由于每次构建时的文档内容一般都会有更改, 所以此处不作为缓存层
FROM initnode as build
WORKDIR /src
COPY ./ ./
RUN yarn build

# 使用nginx镜像作为最终的运行环境, 将构建好的静态文件复制到nginx的默认目录下, 并暴露80端口, 设置时区为上海
# 这里的镜像相比原来的nginx:alpine, 主要添加了上面 build 阶段生成的静态文件
FROM nginx:alpine
WORKDIR /usr/share/nginx/html
EXPOSE 80
ENV TZ=Asia/Shanghai
COPY --from=build /src/build ./
CMD ["nginx", "-g", "daemon off;"]
```

通过使用多阶段构建, 我可以将第一步的包还原阶段生成的文件缓存下来, 以此加快后续build等过程的速度, 只要package.json文件没有变更, 那么在构建时就会直接使用缓存

与此同时最终生成的镜像并不包含第一个阶段中的生成的 node_modules 等文件, 只在最后复制了第二阶段生成的build文件夹, 相比原本的 `nginx:alpine` 镜像只多了十几兆大小